package com.one.group.admin.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.one.group.admin.mapper.PositionMapper;
import com.one.group.enums.ErrorCode;
import com.one.group.model.dto.PositionListDto;
import com.one.group.model.dto.PositionQueryDto;
import com.one.group.model.entity.Position;
import com.one.group.model.vo.PositionVo;
import com.one.group.service.PositionService;
import com.one.group.service.SpCellService;
import com.one.group.utils.ThrowUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @Author wanbo
 * @Date 2025/10/11 15:25
 */
@Slf4j
@Service
public class PositionServiceImpl extends ServiceImpl<PositionMapper, Position> implements PositionService {

    @Autowired
    private PositionMapper positionMapper;

    @Autowired
    private SpCellService spCellService;

    @Override
    public List<PositionVo> selectPositionTree(PositionQueryDto positionQueryDto) {

        String loginId = (String) StpUtil.getLoginId();
        // 获取当前用户是否是管理员
        Long adminId=loginId.equals("1")?0L:Long.valueOf(loginId);

        if (adminId != 0L){
            // 获取当前用户不是管理员的租户id
            // 查询对应用户的岗位信息
            List<Long> positionIdList = positionMapper.getPositionIdByTenantId(Convert.toLong(StpUtil.getExtra("tenant_id")));
            positionQueryDto.setPositionIds(positionIdList);
            positionQueryDto.setTenantId(Convert.toLong(StpUtil.getExtra("tenant_id")));
        } else {
            // 管理员
            List<Long> positionIdList = positionMapper.getPositionIdByTenantId(null);
            positionQueryDto.setPositionIds(positionIdList);
        }

        // 封装一级岗位
        List<PositionVo> positionList = new ArrayList<>();

        // 查询出所有的数据
        List<PositionVo> positions = getMapper().getPositionTree(positionQueryDto);

        // 使用Stream流筛选level为0的数据，并将cellName赋值给name属性
        positions.stream()
                .filter(position -> position.getType() != null && position.getType() == 0)
                .forEach(position -> {
                    if (position.getCellName() != null) {
                        position.setName(position.getCellName());
                    }
                });

        positions.forEach(position -> {
            //判断是否是一级菜单
            if (position.getParentId() == null || position.getParentId() == 0L) {
                //一级
                position.setLevel(0);

                //判断该一级菜单是否存在，如果不存在在添加
                if (existsPosition(positionList, position)) {
                    positionList.add(position);
                }
            }
        });

        //对一级菜单按照顺序进行排序
        positionList.sort((o1, o2) ->
                o1.getOrdered().compareTo(o2.getOrdered()));

        //查找一级菜单子菜单
        findChildren(positionList, positions);

        return positionList;
    }

    @Override
    public Position getPositionById(Long id) {
        if (id == null){
            log.error("id不能为空");
            throw new RuntimeException("id不能为空");
        }

        // 构建条件查询
        QueryWrapper queryWrapper = new QueryWrapper();

        String loginId = (String) StpUtil.getLoginId();
        // 获取当前用户是否是管理员
        Long adminId=loginId.equals("1")?0L:Long.valueOf(loginId);

        if (adminId != 0L){
            queryWrapper.eq(Position::getTenantId,Convert.toLong(StpUtil.getExtra("tenant_id")));
        }

        queryWrapper.eq(Position::getId,id);

        // 查询
        Position position = positionMapper.selectOneByQuery(queryWrapper);

        if (position == null){
            log.error("该{}岗位不存在",id);
            throw new RuntimeException("该岗位不存在");
        }

        return position;
    }

    @Override
    public boolean removePositionAndChild(Long id) {
        if (id == null) {
            log.error("id不能为空");
            throw new RuntimeException("id不能为空");
        }

        // 获取当前登录用户信息
        String loginId = (String) StpUtil.getLoginId();
        Long adminId = loginId.equals("1") ? 0L : Long.valueOf(loginId);

        // 构建查询条件
        QueryWrapper queryWrapper = QueryWrapper.create().from(Position.class);

        if (adminId != 0L) {
            queryWrapper.eq(Position::getTenantId, Convert.toLong(StpUtil.getExtra("tenant_id")));
        }

        queryWrapper.eq(Position::getId, id);

        // 检查要删除的岗位是否存在
        Position position = positionMapper.selectOneByQuery(queryWrapper);
        if (position == null) {
            log.error("该{}岗位不存在", id);
            ThrowUtil.throwIf(true, ErrorCode.PARAMS_ERROR, "id岗位不存在");
        }

        // 获取所有需要删除的岗位ID（包括子岗位）
        List<Long> deleteIds = getAllChildrenIds(id, adminId);
        deleteIds.add(id); // 添加自身ID

        // 执行批量删除
        QueryWrapper deleteWrapper = QueryWrapper.create().from(Position.class);
        deleteWrapper.in(Position::getId, deleteIds);

        return positionMapper.deleteByQuery(deleteWrapper) > 0;
    }

    @Override
    public List<PositionVo> selectPositionTreeByQuery(PositionQueryDto positionQueryDto) {
        if (positionQueryDto.getCellId() != null) {
            positionQueryDto.setCellIds(Arrays.asList(positionQueryDto.getCellId()));
        }

        if(positionQueryDto.getType() != null && positionQueryDto.getType() == 1) {
            // 查询的是部门

            Long adminId = StpUtil.getLoginId().equals("1")?0L:Long.valueOf((String) StpUtil.getLoginId());

            positionQueryDto.setTenantId(adminId.equals(0L)?null:Convert.toLong(StpUtil.getExtra("tenant_id")));

            // 封装一级岗位
            List<PositionVo> positionList = new ArrayList<>();
            // 查询出所有的数据
            List<PositionVo> positions = getMapper().getPositionTreeType2(positionQueryDto);

            // 使用Stream流筛选level为0的数据，并将cellName赋值给name属性
            positions.stream()
                    .filter(position -> position.getType() != null && position.getType() == 0)
                    .forEach(position -> {
                        if (position.getCellName() != null) {
                            position.setName(position.getCellName());
                        }
                    });

            positions.forEach(position -> {
                //判断是否是一级菜单
                if (position.getParentId() == null || position.getParentId() == 0L) {
                    //一级
                    position.setLevel(0);

                    //判断该一级菜单是否存在，如果不存在在添加
                    if (existsPosition(positionList, position)) {
                        positionList.add(position);
                    }
                }
            });

            //对一级菜单按照顺序进行排序
            positionList.sort((o1, o2) ->
                    o1.getOrdered().compareTo(o2.getOrdered()));

            //对一级菜单按照顺序进行排序
            positionList.sort((o1, o2) ->
                    o1.getOrdered().compareTo(o2.getOrdered()));

            //查找一级菜单子菜单
            findChildrenType2(positionList, positions);

            return positionList;
        } else {
            return this.selectPositionTree(positionQueryDto);
        }

    }

    /**
     * 递归获取所有子岗位ID
     * @param parentId 父级ID
     * @param adminId 用户ID
     * @return 所有子岗位ID列表
     */
    private List<Long> getAllChildrenIds(Long parentId, Long adminId) {
        List<Long> result = new ArrayList<>();

        // 构建查询条件
        QueryWrapper queryWrapper = QueryWrapper.create().from(Position.class);
        queryWrapper.select(Position::getId);

        if (adminId != 0L) {
            queryWrapper.eq(Position::getTenantId, Convert.toLong(StpUtil.getExtra("tenant_id")));
        }

        queryWrapper.eq(Position::getParentId, parentId);

        // 查询直接子岗位
        List<Position> children = positionMapper.selectListByQuery(queryWrapper);

        for (Position child : children) {
            result.add(child.getId());
            // 递归获取孙子岗位
            result.addAll(getAllChildrenIds(child.getId(), adminId));
        }

        return result;
    }

    /**
     * 判断菜单是否存在
     * @param positionList
     * @param menu
     * @return
     */
    public boolean existsPosition(List<PositionVo> positionList, PositionVo menu) {
        boolean exist = false;
        for (PositionVo p : positionList) {
            if (p.getId().equals(menu.getId())) {
                exist = true;
            }
        }
        return !exist;
    }

    /**
     * 遍历菜单
     * @param positionList  一级目录集合
     * @param positions  该用户的所有权限
     */
    public void findChildrenType2(List<PositionVo> positionList, List<PositionVo> positions) {

        //遍历所一级目录
        //遍历所有二级目录
        for (PositionVo position : positionList) {

            //准备子菜单集合
            List<PositionVo> children = new ArrayList<>();

            //从查询到的菜单中查找子菜单
            for (PositionVo p : positions) {

                //判断是否岗位，如果是按钮直接跳过
                if (position.getType() == 1) {
                    continue;
                }

                //如果当前遍历的子菜单的父级id是一级菜单  则加入该一级菜单的子集合中
                if (position.getId() != null && position.getId().equals(p.getParentId())) {
                    //设置父菜单名字
                    p.setParentName(position.getName());
                    //设置菜单登记
                    p.setLevel(position.getLevel() + 1);
                    //如果不存在该菜单则进行添加操作
                    if (existsPosition(children, p)) {
                        children.add(p);
                    }
                }
            }

            //将子菜单加入一级菜单中
            position.setChildren(children);

            //子菜单排序
            children.sort((o1, o2) -> o1.getOrdered().compareTo(o2.getOrdered()));

            //继续递归查找
            findChildren(children, positions);
        }

    }

    /**
     * 遍历菜单
     * @param positionList  一级目录集合
     * @param positions  该用户的所有权限
     */
    public void findChildren(List<PositionVo> positionList, List<PositionVo> positions) {

        //遍历所一级目录
        //遍历所有二级目录
        for (PositionVo position : positionList) {

            //准备子菜单集合
            List<PositionVo> children = new ArrayList<>();

            //从查询到的菜单中查找子菜单
            for (PositionVo p : positions) {

                //判断是否岗位，如果是按钮直接跳过
                if (position.getType() == 2) {
                    continue;
                }

                //如果当前遍历的子菜单的父级id是一级菜单  则加入该一级菜单的子集合中
                if (position.getId() != null && position.getId().equals(p.getParentId())) {
                    //设置父菜单名字
                    p.setParentName(position.getName());
                    //设置菜单登记
                    p.setLevel(position.getLevel() + 1);
                    //如果不存在该菜单则进行添加操作
                    if (existsPosition(children, p)) {
                        children.add(p);
                    }
                }
            }

            //将子菜单加入一级菜单中
            position.setChildren(children);

            //子菜单排序
            children.sort((o1, o2) -> o1.getOrdered().compareTo(o2.getOrdered()));

            //继续递归查找
            findChildren(children, positions);
        }

    }

}
